package com.sanbi.shield.client.core.idempotent;

import com.sanbi.shield.client.core.exceptions.IdempotentException;
import com.sanbi.shield.server.facade.annotations.ClientIdempotent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.Advised;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.lang.NonNull;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;

/**
 * Client幂等Bean后置处理器
 *
 * @author XiaoQingqing
 * @since 2024/08/22
 */
@Slf4j
public class ClientIdempotentBeanProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(@NonNull Object bean, @NonNull String beanName) throws BeansException {
        if (bean instanceof Advised target) {
            try {
                Object targetObject = target.getTargetSource().getTarget();
                if(null != targetObject){
                    for (Method method : targetObject.getClass().getMethods()) {
                        ClientIdempotent clientIdempotent = method.getAnnotation(ClientIdempotent.class);
                        if(null != clientIdempotent){
                            if(!StringUtils.hasText(clientIdempotent.methodKey()) || !StringUtils.hasText(clientIdempotent.key())){
                                throw new IdempotentException("方法标识或幂等键为空");
                            }
                            ClientIdempotentHandlerCache.push(clientIdempotent.methodKey(), target.getTargetSource().getTarget(), method);
                        }
                    }
                }
            } catch (Exception e) {
                log.error("缓存幂等处理方法发生未知异常", e);
                throw new IdempotentException(e);
            }
        }
        return bean;
    }
}
